package com.leo.foodmaster.admin.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.leo.foodmaster.admin.system.entity.Dept;
import com.leo.foodmaster.admin.system.entity.Organ;
import com.leo.foodmaster.admin.system.entity.SysUser;
import com.leo.foodmaster.admin.system.mapper.DeptMapper;
import com.leo.foodmaster.admin.system.service.IDeptService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leo.foodmaster.admin.system.service.IOrganService;
import com.leo.foodmaster.admin.system.service.IUserService;
import com.leo.foodmaster.commons.entity.Result;
import com.leo.foodmaster.commons.entity.TreeSelect;
import com.leo.foodmaster.commons.enums.OrganTypeEnum;
import com.leo.foodmaster.commons.enums.StatusEnum;
import com.leo.foodmaster.commons.util.WebUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 部门表 服务实现类
 * </p>
 *
 * @author Leo
 * @since 2021-07-15
 */
@Service
@AllArgsConstructor
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements IDeptService {
    private final IOrganService organService;
    private final IUserService userService;


    /**
     * 条件分页查询部门列表
     * @param page 分页参数
     * @param organId 公司Id
     * @param name 部门名称
     * @param status 部门状态
     * @param beginTime 开始时间
     * @param endTime 结束时间
     * @return IPage<Dept>
     */
    @Override
    public IPage<Dept> getOrganPageList(Page<Dept> page, Long organId, String name, String status, String beginTime, String endTime) {
        String organType = WebUtils.getUser().getOrganType();
        LambdaQueryWrapper<Dept> qw = Wrappers.lambdaQuery(Dept.class)
                .like(StrUtil.isNotBlank(name), Dept::getName, name)
                .eq(StrUtil.isNotBlank(status), Dept::getStatus, status)
                .ge(StrUtil.isNotBlank(beginTime), Dept::getCreateTime, beginTime)
                .le(StrUtil.isNotBlank(endTime), Dept::getCreateTime, endTime);
        // 如果登录的是平台用户，organId为空时查询所有部门
        if (!OrganTypeEnum.PLATFORM.getCode().equals(organType) && BeanUtil.isEmpty(organId)) {
            organId = WebUtils.getUser().getOrganId();
        }
        qw.eq(BeanUtil.isNotEmpty(organId), Dept::getOrganId, organId);
        return page(page, qw);
    }

    /**
     * 查询所有部门树形列表
     * @param organId 公司Id
     * @return List<TreeSelect>
     */
    @Override
    public List<TreeSelect> treeSelect(Long organId) {
        String organType = WebUtils.getUser().getOrganType();
        if (!OrganTypeEnum.PLATFORM.getCode().equals(organType) && BeanUtil.isEmpty(organId)) {
            organId = WebUtils.getUser().getOrganId();
        }
        List<Dept> list = list(Wrappers.lambdaQuery(Dept.class)
                .eq(BeanUtil.isNotEmpty(organId), Dept::getOrganId, organId));

        return handleTreeSelect(list);
    }

    /**
     * 新增部门
     * @param dept 部门信息
     * @return Result<Object>
     */
    @Override
    public Result<Object> addOrgan(Dept dept) {
        String organType = WebUtils.getUser().getOrganType();
        // 如果父部门被禁用，不允许新增子部门
        Dept parentDept = getById(dept.getParentId());
        if (BeanUtil.isNotEmpty(parentDept) ) {
            if (StatusEnum.DISABLED.getCode().equals(parentDept.getStatus())) {
                return Result.fail("上级部门被禁用，不能新增！");
            }
            dept.setAncestors(parentDept.getAncestors() + StrUtil.COMMA + dept.getParentId());
            String[] split = parentDept.getAncestors().split(StrUtil.COMMA);
            dept.setType(String.valueOf(split.length + 1));
        }else {
            dept.setParentId(0L);
            dept.setAncestors("0");
            dept.setType("1");
        }

        // 如果登录用户所属公司不是平台
        if (!OrganTypeEnum.PLATFORM.getCode().equals(organType)) {
            dept.setOrganId(WebUtils.getUser().getOrganId());
        }
        Organ organ = organService.getById(dept.getOrganId());
        dept.setOrganName(organ.getName());
        save(dept);
        return Result.success();
    }

    /**
     * 修改部门
     * @param dept 部门信息
     * @return Result<Object>
     */
    @Override
    public Result<Object> updateDept(Dept dept) {
        Dept parentDept = getById(dept.getParentId());
        if (BeanUtil.isNotEmpty(parentDept)) {
            dept.setAncestors(parentDept.getAncestors() + StrUtil.COMMA + dept.getParentId());
            String[] split = parentDept.getAncestors().split(StrUtil.COMMA);
            dept.setType(String.valueOf(split.length + 1));
        }else {
            dept.setParentId(0L);
            dept.setAncestors("0");
            dept.setType("1");
        }

        Organ organ = organService.getById(dept.getOrganId());
        dept.setOrganName(organ.getName());
        updateById(dept);
        return Result.success();
    }

    /**
     * 删除部门
     * @param deptId 部门Id
     * @return Result<Object>
     */
    @Override
    public Result<Object> deleteDept(String deptId) {
        // 如果该部门下有用户则不能删除
        int userCount = userService.count(Wrappers.lambdaQuery(SysUser.class)
                .eq(SysUser::getDeptId, deptId));
        if (userCount != 0) {
            return Result.fail("该部门下有用户，不能删除！");
        }
        // 如果该部门有子部门，不能删除
        int deptCount = count(Wrappers.lambdaQuery(Dept.class)
                .eq(Dept::getParentId, deptId));
        if (deptCount != 0) {
            return Result.fail("该部门下有子部门，不能删除！");
        }
        // 删除部门
        removeById(deptId);

        return Result.success();
    }

    /**
     * 组装树形列表
     * @param list 源列表
     * @return List<TreeSelect>
     */
    private List<TreeSelect> handleTreeSelect(List<Dept> list) {
        List<TreeSelect> treeSelectList = new ArrayList<>();
        list.forEach(item -> {
            if (item.getParentId() == 0) {
                TreeSelect treeSelect = new TreeSelect(item.getId(), item.getName());
                treeSelectList.add(treeSelect);
            }
        });
        if (!treeSelectList.isEmpty()) {
            getChildren(treeSelectList, list);
        }
        return treeSelectList;
    }

    /**
     * 从list中选出子树
     * @param treeSelectList 父树
     * @param list 源
     */
    private void getChildren(List<TreeSelect> treeSelectList, List<Dept> list) {
        treeSelectList.forEach(tree -> {
            List<TreeSelect> children = new ArrayList<>();
            list.forEach(dept -> {
                if (dept.getParentId().equals(tree.getId())) {
                    TreeSelect treeSelect = new TreeSelect(dept.getId(), dept.getName());
                    children.add(treeSelect);
                }
            });
            if (!children.isEmpty()) {
                tree.setChildren(children);
                getChildren(children, list);
            }
        });
    }
}
